package csel.view.status;

import java.awt.Color;
import javax.swing.*;

import csel.model.*;
import csel.model.items.*;
import csel.view.*;

public class InventoryBar extends JPanel implements Observer<Object>, IndexedBar
{

	private static final long serialVersionUID = 1L;
	
	private ItemCollection<UseableItem> myUseableInv;
	private ItemCollection<EquippableItem> myEquippableInv;
	
	private int startIndex;
	private int modeIndex;
	private char currentMode; // u is useable only, e is equippable only, b is both
	
	private JLabel[] itemLabels;
	private JLabel currentIcon;
	private JLabel rotateIcon;
	private JLabel skillIcon;
	private JLabel equipmentIcon;
	
	private ImageIcon useIcon;
	private ImageIcon equipIcon;
	private ImageIcon dropUseIcon;
	private ImageIcon dropEquipIcon;
	private ImageIcon throwIcon;
	private ImageIcon emptyIcon;
	
	public static InventoryBar initialize(ItemCollection<UseableItem> useInv, ItemCollection<EquippableItem> equipInv)
	{
		InventoryBar myInvBar = new InventoryBar(useInv, equipInv);
		useInv.addObserver(myInvBar);
		equipInv.addObserver(myInvBar);
		return myInvBar;
	}
	
	private InventoryBar(ItemCollection<UseableItem> myUseableInv, ItemCollection<EquippableItem> myEquippableInv)
	{
		this.myUseableInv = myUseableInv;
		this.myEquippableInv = myEquippableInv;
		
		setLayout(new BoxLayout(this,BoxLayout.LINE_AXIS));
		
		itemLabels = new JLabel[10];
		for (int a = 0; a < 10; ++a)
		{
			JLabel tempLabel = new JLabel(Integer.toString((a+1) % 10));
			tempLabel.setVerticalAlignment(JLabel.NORTH);
			tempLabel.setForeground(Color.white);
			
			add(tempLabel);
			add(itemLabels[a] = new JLabel());
		}

		rotateIcon = ImageLoader.makeLabel("rotate_icon");
		equipmentIcon = ImageLoader.makeLabel("equip_mode_icon");
		skillIcon = ImageLoader.makeLabel("skill_mode_icon");

		
		useIcon = ImageLoader.makeIcon("use_item_icon");
		equipIcon = ImageLoader.makeIcon("equip_item_icon");
		dropUseIcon = ImageLoader.makeIcon("dropuse_item_icon");
		dropEquipIcon = ImageLoader.makeIcon("dropequip_item_icon");
		throwIcon = ImageLoader.makeIcon("throw_item_icon");
		emptyIcon = ImageLoader.makeIcon("emptyslot");
		
		currentIcon = new JLabel(useIcon);
		
		JLabel tempLabel1 = new JLabel(" - ");
		tempLabel1.setVerticalAlignment(JLabel.NORTH);
		tempLabel1.setForeground(Color.white);
		add(tempLabel1);
		add(currentIcon);
		
		JLabel tempLabel2 = new JLabel(" = ");
		tempLabel2.setVerticalAlignment(JLabel.NORTH);
		tempLabel2.setForeground(Color.white);
		add(tempLabel2);
		add(rotateIcon);
		
		JLabel tempLabel3 = new JLabel(" E ");
		tempLabel3.setVerticalAlignment(JLabel.NORTH);
		tempLabel3.setForeground(Color.white);
		add(tempLabel3);
		add(equipmentIcon);
		
		JLabel tempLabel4 = new JLabel(" T ");
		tempLabel4.setVerticalAlignment(JLabel.NORTH);
		tempLabel4.setForeground(Color.white);
		add(tempLabel4);
		add(skillIcon);
		
		setMode(modeIndex);
		setLabels();
		
		setOpaque(false);
	}
	
	public void rotate()
	{
		int totalItems = 0;
		
		if (currentMode == 'u')
			totalItems = myUseableInv.size();
		else if (currentMode == 'e')
			totalItems = myEquippableInv.size();

		if (totalItems <= 10)
			return;
		
		startIndex += 10;
		if (startIndex > totalItems)
			startIndex = 0;
		
		setLabels();
	}
	
	public int getOffset()
	{
		return startIndex;
	}
	
	private void setLabels()
	{
		int totalItems = 0;
		int upperBound = startIndex+10;
		int index = 0;
		
		if (currentMode == 'u') //if in useable items only mode
		{
			totalItems = myUseableInv.size();
			for (int a = startIndex; (a < totalItems)&&(a < upperBound); ++a)
			{
				itemLabels[index++].setIcon(new ImageIcon(RepresentationFactory.getInstance().get(myUseableInv.getItem(a)).getIconImage()));
			}
			while (index < 10)
			{
				itemLabels[index++].setIcon(emptyIcon);
			}
		}
		else if (currentMode == 'e') //if in equippable items only mode
		{
			totalItems = myEquippableInv.size();
			for (int a = startIndex; (a < totalItems)&&(a < upperBound); ++a)
			{
				itemLabels[index++].setIcon(new ImageIcon(RepresentationFactory.getInstance().get(myEquippableInv.getItem(a)).getIconImage()));
			}
			while (index < 10)
			{
				itemLabels[index++].setIcon(emptyIcon);
			}
		}

		revalidate();
		repaint();
	}
	
	public void mupdate(Object o, Object param)
	{
		if (o.equals(myUseableInv) || o.equals(myEquippableInv))
		{
			//TODO: make this not reset the index if not necessary
			startIndex = 0;
			setLabels();
		}
	}
	
	public void setInventories(ItemCollection<UseableItem> myUseableInv, ItemCollection<EquippableItem> myEquippableInv)
	{
		this.myUseableInv = myUseableInv;
		this.myEquippableInv = myEquippableInv;
		myUseableInv.addObserver(this);
		myEquippableInv.addObserver(this);
		setLabels();
	}
	
	public void setMode(int i)
	{
		startIndex = 0;
		modeIndex = i;
		
		if (i == 0)
		{
			//change icons
			currentMode = 'u';
			currentIcon.setIcon(useIcon);
		}
		else if (i == 1)
		{
			//change icons
			currentMode = 'e';
			currentIcon.setIcon(equipIcon);
		}
		else if (i == 2)
		{
			//change icons
			currentMode = 'u';
			currentIcon.setIcon(dropUseIcon);
		}
		else if (i == 3)
		{
			//change icons
			currentMode = 'e';
			currentIcon.setIcon(dropEquipIcon);
		}
		else
		{
			//change icons
			currentMode = 'u';
			currentIcon.setIcon(throwIcon);
		}

		setLabels();
	}
	
	public void nextMode()
	{
		modeIndex = ++modeIndex % 5;
		setMode(modeIndex);
	}
	
	private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException
    {
            throw new java.io.NotSerializableException("InventoryBar should not be serialized.");
    }
    
    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException
    {
            throw new java.io.NotSerializableException("InventoryBar should not be serialized.");
    }

}